/*
The surface-physics project: http://code.google.com/p/surface-physics/
Adds real world physics based on the Bullet physics engine, to bases in the Orbiter space
flight simulation software.

Written by Abhijit Nandy
License : Apache License 2.0

Bump_TerrainPatch.h
Terrain Patch management

This file declares the Bump_TerrainPatch base class.

It supports a basic triangle mesh terrain that follows the smooth spherical planetary surface.
NO Orulex here !! This is the base class in the terrain patch hierarchy


				Bump_TerrainPatch
                /              \
Bump_TerrainPatchOru         Bump_TerrainPatchD3D11


The patch class is used as follows for objects which are in contact/affected by terrain


	The patch has the longitude and latitude limits which it covers on the surface
	Due to the spherical shape the patch area decreases as we approach the poles as the long. span remains
	same and they converge.
	These are the rules followed by objects(which are affected by terrain) :

	1.An object maintains its own supporting terrain patch

	2.The patch is updated by passing the current vehicle position wrt base in terms of lng, lat (rad not imp.)
	  No camera worries here as planetary data always available, unlike Orulex.

	2.1 All terrain patches are actually positioned at 0,0,0 - This may lead to problems later.
	  Only their vertices are updated to remain under the object its supporting. Its something like this :


	  _____
	  \    \
	   \    \
	    \   \
	     \   \
	      \   \           _____
	       \   \         /    /
	        \   \       /    /
	         \  \      /    /
	          \ \     /   /
	           \ \   /   /
	            \\  /  /
	             \\ / /
	              \ /
                0, 0, 0

      So if we try to get the current position of the patch rigid body it will always be 0,0,0
      We must use the bounding sphere center or AABB center which uses the bounding region of the
      vertices to give the actual center of the vertices.

      The patches are static rigid bodies


	3.Terrain updates are done in prestep() of object

	4.Terrain patch with partialRefit() and triangles added as required are currently enough to support vehicle.

	5. We would have liked to increase/decrease the patch area based on the velocity vector - maybe later


Note: this method is independent of direction of movement of object on planet. Its based purely on values of longitude
& latitude.


*/


#pragma once


#include "../BulletBase/Bump_BaseObject.h"


/**
 * The Bump_TerrainPatch to create and manage a supporting terrain
 */
class Bump_TerrainPatch 
{

protected:
	/* Terrain related constants */
	//Max points in 1 dimension: SHOULD BE POWER OF 2(for speed), max. quads is MAX_POINTS-1 in 1 dim
	//This is also the number of latitudes and longitudes used to get points(the points are their intersection)
	unsigned int lngMaxPoints, latMaxPoints;
	unsigned int lngMaxQuads,  latMaxQuads;

	//Total no. of quads is (MAX_POINTS-1)*(MAX_POINTS-1), 2 triangle/quad, 3 vertices per triangle.
	unsigned int maxIndices;

	//The increment amount to lola, single point precision is 7 digits, double should cover 6 digits
	double lngAngleIncr, latAngleIncr;

	double lngBorderWidth, latBorderWidth;
	double lngMidpoint, latMidpoint;
	double updateDistance;

	btVector3 *vertices;
	int *indices;

	//Vertices, collision shape and rigid body for this patch
	btTriangleIndexVertexArray*	m_indexVertexArrays;
	btBvhTriangleMeshShape* collshpTerrainPatch;
	btCollisionShape *mcollshpSupportPlate;

	//Terrain patch coverage area on body sphere
	double equLngStart, equLngEnd, equLatStart, equLatEnd;


	//The surface point corresponding to equLngStart and equLatStart in base frame
	VECTOR3 rposSurfStartPoint;	

	//Required during terrain creation and refit
	btVector3 aabbMin, aabbMax;

	Bump_BulletBase *bumpBase;


public:

	//This is needed to allow base objects to set focus on base ground rb before being deleted
	//for the visualizer only
	btRigidBody *mrbTerrainPatch, *mrbSupportPlate;

	Bump_TerrainPatch(unsigned int lngMaxPoints, unsigned int latMaxPoints,
					  double lngAngleIncr, double latAngleIncr,
					  double lngBorder, double latBorder,
					  double updateDistance,
					  Bump_BulletBase *base);
	virtual ~Bump_TerrainPatch();

	//Terrain patch interface
	virtual int createPatch(double lng, double lat);
	virtual int updatePatch(double lng, double lat, double rad);
	virtual int setTerrainVertices();
};


